package com.company.eos.service.impl;

import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.eos.common.util.PageUtils;
import com.company.eos.mapper.*;
import com.company.eos.domain.*;
import com.company.eos.service.AuditDetailService;
import com.company.eos.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author Real
 * @description 针对表【tb_audit_detail(OA审批流详情表)】的数据库操作Service实现
 * @createDate 2022-04-28 13:00:00
 */
@Service
public class AuditDetailServiceImpl extends ServiceImpl<AuditDetailMapper, AuditDetail>
        implements AuditDetailService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private AuditDetailMapper auditDetailMapper;
    @Autowired
    private UserService userService;
    @Resource
    private AuditFlowMapper auditFlowMapper;
    @Resource
    private AuditQuitMapper auditQuitMapper;
    @Resource
    private AuditLeaveMapper auditLeaveMapper;
    @Resource
    private AuditExpenseMapper auditExpenseMapper;
    @Resource
    private AuditMeetingMapper auditMeetingMapper;

    @Override
    public int insertAuditQuit(AuditQuit quit, AuditFlow flow) {
        return this.insertAudit(quit.getApplyUserId(), flow);
    }

    @Override
    public int insertAuditLeave(AuditLeave auditLeave, AuditFlow flow) {
        return this.insertAudit(auditLeave.getUserId(), flow);
    }

    @Override
    public int insertAuditExpense(AuditExpense expense, AuditFlow flow) {
        return this.insertAudit(expense.getUserId(), flow);
    }

    @Override
    public int insertAuditMeeting(AuditMeeting meeting, AuditFlow flow) {
        AuditDetail detail = new AuditDetail();
        // 申请人Id
        Integer creatorId = meeting.getCreatorId();
        detail.setAuditStatus("待审批");
        // 审批人设置，查询申请人基本信息
        HashMap info = userMapper.searchUserInfo(creatorId);
        // 判断申请的人角色是否包含总经理
        String[] roles = info.get("roles").toString().split(",");
        // 不包含总经理的话， 则获取总经理的userId和部门经理userId
        if (!ArrayUtil.contains(roles, "总经理")) {
            // 查询部门经理Id
            Integer deptManagerId = userMapper.searchDeptManagerId(creatorId);
            if (deptManagerId != null) {
                detail.setAuditUserId(deptManagerId);
            } else {
                // 查询总经理Id
                Integer managerId = userMapper.searchGmId();
                if (managerId != null) {
                    detail.setAuditUserId(managerId);
                }
            }
        }
        // 再次确认是否有审批人，若没有，直接交给管理员
        // 且若角色为总经理，也将会议申请交给管理员审批
        if (detail.getAuditUserId() == null) {
            detail.setAuditUserId(userMapper.selectById(1).getId());
        }
        // 看是否参会人在同一部门
        boolean bool = auditMeetingMapper.searchMeetingMembersInSameDept(meeting.getUuid());
        detail.setFlowId(flow.getId());
        detail.setAuditStatus("待审批");
        return auditDetailMapper.insert(detail);
    }

    private int insertAudit(Integer userId, AuditFlow flow) {
        AuditDetail detail = new AuditDetail();
        detail.setAuditStatus("待审批");
        // 申请人
        User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getId, userId));
        User depManager = userService.getDepManager(user);
        // 审批人设置
        detail.setAuditUserId(depManager.getId());
        detail.setFlowId(flow.getId());
        detail.setAuditStatus("待审批");
        return auditDetailMapper.insert(detail);
    }

    /**
     * 查询审批详情，只能查询到是我自己的任务的审批
     *
     * @param param
     * @return
     */
    @Override
    public PageUtils searchTaskByPage(HashMap param) {
        ArrayList<HashMap> list = auditDetailMapper.searchAuditByPage(param);
        long count = auditDetailMapper.searchAuditCount(param);

        int start = (Integer) param.get("page");
        int length = (Integer) param.get("length");
        return new PageUtils(list, count, start, length);
    }

    @Override
    public HashMap searchAuditContent(HashMap param) {
        // 参数有userId、role、flowId、type、status
        // 先解决离职申请
        // 查询的有：原因、姓名、时间、status
        Integer flowId = Integer.parseInt(param.get("flowId").toString());
        String type = param.get("type").toString();
        AuditFlow flow = auditFlowMapper.selectOne(Wrappers.lambdaQuery(AuditFlow.class)
                .eq(AuditFlow::getId, flowId));
        Integer applyUserId = flow.getApplyUserId();
        User user = userMapper.selectById(applyUserId);
        if ("员工离职".equals(type)) {
            HashMap<Object, Object> result = new HashMap<Object, Object>() {{
                put("date", new SimpleDateFormat("yyyy-MM-dd").format(flow.getApplyTime()));
                put("applyUserName", user.getName());
                put("applyReason", flow.getApplyReason());
                put("status", flow.getApplyStatus());
                put("applyType", flow.getApplyType());
            }};
            return result;
        } else if ("员工请假".equals(type)) {
            AuditLeave auditLeave = auditLeaveMapper.selectOne(Wrappers.lambdaQuery(AuditLeave.class)
                    .eq(AuditLeave::getFlowId, flowId));
            HashMap<Object, Object> result = new HashMap<Object, Object>() {{
                put("date", new SimpleDateFormat("yyyy-MM-dd").format(flow.getApplyTime()));
                put("applyUserName", user.getName());
                put("applyReason", flow.getApplyReason());
                put("status", flow.getApplyStatus());
                put("applyType", flow.getApplyType());
                put("start", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(auditLeave.getStart()));
                put("end", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(auditLeave.getEnd()));
            }};
            return result;
        } else if ("报销申请".equals(type)) {
            AuditExpense expense = auditExpenseMapper.selectOne(Wrappers.lambdaQuery(AuditExpense.class)
                    .eq(AuditExpense::getFlowId, flowId));
            HashMap<Object, Object> result = new HashMap<Object, Object>() {{
                put("date", new SimpleDateFormat("yyyy-MM-dd").format(flow.getApplyTime()));
                put("applyUserName", user.getName());
                put("amount", expense.getAmount());
                put("status", flow.getApplyStatus());
                put("applyType", flow.getApplyType());
                put("anleihen", expense.getAnleihen());
                put("balance", expense.getBalance());
                put("type", expense.getTypeId() == 1 ? "普通报销" : "差旅报销");
            }};
            return result;
        } else if ("会议申请".equals(type)) {
            // 查询会议详情信息
            AuditMeeting auditMeeting = auditMeetingMapper.selectOne(Wrappers.lambdaQuery(AuditMeeting.class)
                    .eq(AuditMeeting::getFlowId, flowId));
            // 1在线会议，2线下会议
            String place = auditMeeting.getType() == 1 ? "在线会议" : auditMeeting.getPlace();
            // 查看会议详情需要显示哪些信息
            HashMap<Object, Object> result = new HashMap<Object, Object>() {{
                // applyTitle desc date start end place members status
                put("date", new SimpleDateFormat("yyyy-MM-dd").format(flow.getApplyTime()));
                put("applyTitle", auditMeeting.getTitle());
                put("desc", auditMeeting.getDescription());
                put("start", new SimpleDateFormat("HH:mm:ss").format(auditMeeting.getStart()));
                put("end", new SimpleDateFormat("HH:mm:ss").format(auditMeeting.getEnd()));
                put("status", flow.getApplyStatus());
                put("place", place);
                // 查询参会人员姓名
                String s = auditMeeting.getMembers().toString();
                if (s.length() == 2) {
                    // 表示没有参会人员
                    put("members", null);
                } else {
                    List<String> nameList = new ArrayList<>();
                    String substring = s.substring(1, s.length() - 1);
                    // 参会人员的ID
                    String[] split = substring.split(",");
                    for (String sp : split) {
                        String s1 = sp.replaceAll(" +", "");
                        int i = Integer.parseInt(s1);
                        String name = userMapper.selectById(i).getName();
                        nameList.add(name);
                    }
                    String join = String.join("、", nameList);
                    put("members", join);
                }
            }};
            return result;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditTask(HashMap param) {
        Integer flowId = Integer.parseInt(param.get("flowId").toString());
        // 获取任务
        AuditFlow flow = auditFlowMapper.selectOne(Wrappers.lambdaQuery(AuditFlow.class)
                .eq(AuditFlow::getId, flowId));
        AuditDetail detail = auditDetailMapper.selectOne(Wrappers.lambdaQuery(AuditDetail.class)
                .eq(AuditDetail::getFlowId, flowId));
        // 设置时间
        detail.setAuditTime(new Date());
        Integer applyUserId = flow.getApplyUserId();
        User user = userMapper.selectById(applyUserId);
        String approval = param.get("approval").toString();
        if ("同意".equals(approval)) {
            detail.setAuditStatus("已结束");
            flow.setApplyStatus("已同意");
        } else if ("否决".equals(approval)) {
            detail.setAuditStatus("已结束");
            flow.setApplyStatus("已拒绝");
        }
        auditDetailMapper.update(detail, Wrappers.lambdaQuery(AuditDetail.class)
                .eq(AuditDetail::getId, detail.getId()));
        auditFlowMapper.update(flow, Wrappers.lambdaQuery(AuditFlow.class)
                .eq(AuditFlow::getId, flow.getId()));
        switch (flow.getApplyType()) {
            case "员工离职":
                AuditQuit quit = auditQuitMapper.selectOne(Wrappers.lambdaQuery(AuditQuit.class)
                        .eq(AuditQuit::getApplyUserId, applyUserId)
                        // 表示查询还未审批的
                        .eq(AuditQuit::getStatus, 1));
                quit.setStatus("同意".equals(approval) ? 2 : 3);
                auditQuitMapper.update(quit, Wrappers.lambdaQuery(AuditQuit.class)
                        .eq(AuditQuit::getId, quit.getId()));
                break;
            case "员工请假":
                AuditLeave auditLeave = auditLeaveMapper.selectOne(Wrappers.lambdaQuery(AuditLeave.class)
                        .eq(AuditLeave::getFlowId, flow.getId()));
                auditLeave.setStatus("同意".equals(approval) ? Byte.valueOf("3") : Byte.valueOf("2"));
                auditLeaveMapper.update(auditLeave, Wrappers.lambdaQuery(AuditLeave.class)
                        .eq(AuditLeave::getId, auditLeave.getId()));
                break;
            case "报销申请":
                AuditExpense expense = auditExpenseMapper.selectOne(Wrappers.lambdaQuery(AuditExpense.class)
                        .eq(AuditExpense::getFlowId, flow.getId()));
                // 2已拒绝，3审批通过
                expense.setStatus("同意".equals(approval) ? 3 : 2);
                auditExpenseMapper.update(expense, Wrappers.lambdaQuery(AuditExpense.class)
                        .eq(AuditExpense::getId, expense.getId()));
                break;
            case "会议申请":
                AuditMeeting auditMeeting = auditMeetingMapper.selectOne(Wrappers.lambdaQuery(AuditMeeting.class)
                        .eq(AuditMeeting::getFlowId, flow.getId()));
                // 2.审批未通过，3.审批通过
                auditMeeting.setStatus("同意".equals(approval) ? 3 : 2);
                auditMeetingMapper.update(auditMeeting, Wrappers.lambdaQuery(AuditMeeting.class)
                        .eq(AuditMeeting::getId, auditMeeting.getId()));
                break;
            default:
                break;
        }
    }

    @Override
    public int deleteAudit(int flowId) {
        AuditFlow flow = auditFlowMapper.selectById(flowId);
        String type = flow.getApplyType();
        // 删除两个审批表
        auditDetailMapper.delete(Wrappers.lambdaQuery(AuditDetail.class)
                .eq(AuditDetail::getFlowId, flow.getId()));
        auditFlowMapper.delete(Wrappers.lambdaQuery(AuditFlow.class)
                .eq(AuditFlow::getId, flowId));
        switch (type) {
            case "员工离职":
                // 已经在其他地方删除
                break;
            case "员工请假":
                // 请假自身已进行过删除
                break;
            case "报销申请":
                // 报销不需要删除
                break;
            case "会议申请":
                // 会议是否需要删除
                break;
        }
        return 0;
    }


}




